﻿using PersistentObject.Common.Criteria;
using PersistentObject.Common.Schema;
using PersistentObject.Common.Sorts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PersistentObject.Common
{
    public class BaseDialectNamingPattern
    {
        public virtual string GetColumnAlias(Column column)
        {
            Table table = column.Table;
            var tableAlias = GetTableAlias(table);
            var alias = string.Format("{0}__{1}", tableAlias, column.ColumnName);
            return alias;
        }

        public virtual string GetTableAlias(Table table)
        {
            var alias = "";
            if (table.IsInnerExists)
            {
                alias = string.Format("inner__{0}__{1}", table.TableName, table.Sequence);
            }
            else
            {
                alias = string.Format("{0}__{1}", table.TableName, table.Sequence);
            }
            return alias;
        }

        public virtual string GetSaveParameterName(Column column)
        {
            Table table = column.Table;
            var tableAlias = GetTableAlias(table);
            string pname = string.Format("@{0}__{1}", tableAlias, column.ColumnName);
            return pname;
        }

        public virtual string GetDeleteParameterName(Column column)
        {
            string pname = "@" + GetColumnAlias(column);
            return pname;
        }

        public virtual string GetFullHashKey(Column column)
        {
            var header = GetColumnAlias(column);
            int columnSequence = 0;
            string fullHashKey = GetColumnHashKey(header, columnSequence);
            return fullHashKey;
        }

        public virtual string GetSimpleHashKey(Column column)
        {
            var header = column.ColumnName;
            int columnSequence = column.Sequence;
            string simpleHashKey = GetColumnHashKey(header, columnSequence);
            return simpleHashKey;
        }

        public virtual string GetColumnHashKey(string header, int columnSequence)
        {
            var hashKey = string.Format("{0}__{1}", header, columnSequence);
            return hashKey;
        }

        public virtual string GetOperandValueParameterName(OperandValue ov)
        {
            string pname = string.Format("@{0}", ov.ParameterName);
            return pname;
        }

        public virtual string GetOrderByTypeClause(OrderByType type)
        {
            switch (type)
            {
                case OrderByType.DESC:
                    return "DESC";
                case OrderByType.ASC:
                    return "ASC";
                default:
                    throw new NotImplementedException();
            }
        }

        public virtual string GetAggregateName(AggregateTypes type)
        {
            switch (type)
            {
                case AggregateTypes.Count:
                    return "COUNT";
                case AggregateTypes.Sum:
                    return "SUM";
                case AggregateTypes.Average:
                    return "AVG";
                case AggregateTypes.Max:
                    return "MAX";
                case AggregateTypes.Min:
                    return "MIN";
                default:
                    throw new NotImplementedException();
            }
        }

        public virtual string GetColumnNameWithTableNameInQuote(Column column)
        {
            var table = column.Table;
            var clause = string.Format("[{0}].[{1}]",
                table.TableName,
                column.ColumnName);
            return clause;
        }

        public virtual string GetColumnNameWithTableAliasInQuote(Column column)
        {
            var table = column.Table;
            var tableAlias = GetTableAlias(table);
            var clause = string.Format("[{0}].[{1}]",
                tableAlias,
                column.ColumnName
            );
            return clause;
        }

        public virtual string GetColumnNameInQuote(Column column)
        {
            var clause = string.Format("[{0}]", column.ColumnName);
            return clause;
        }

        public virtual string GetColumnAliasInQuote(Column column)
        {
            var alias = GetColumnAlias(column);
            var clause = string.Format("[{0}]", alias);
            return clause;
        }

        public virtual string GetTableNameInQuote(Table table)
        {
            var clause = string.Format("[{0}]", table.TableName);
            return clause;
        }

        public virtual string GetTableAliasInQuote(Table table)
        {
            var tableAlias = GetTableAlias(table);
            var clause = string.Format("[{0}]", tableAlias);
            return clause;
        }
    }
}
